package com.zhiyou100.api.date_demo;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类：
 * 1、字符串转Date （根据日期以及格式进行转换）
 * 2、Date转字符串  （根据指定的格式将Date转换成字符串）
 * 3、使用默认格式yyyy-MM-dd将Date转字符串
 * 4、使用默认格式yyyy-MM-dd将字符串日期转Date
 * 5、获取两个指定日期的相差天数
 * 6、根据输入的日期计算年龄
 * 7、获取指定日期为所在周的星期几的日期
 * 8、根据传入的毫秒值返回字符串类型日期
 * 9、判断时间是否在指定的时间段之内
 * 10、获取当前周截止时间
 * 11、获取当前周开始时间
 * 12、获取某月多少天
 */
public class DateUtils {

    /**
     * 字符串转Date （根据日期以及格式进行转换）
     *
     * @param date 日期字符串
     * @param form 格式
     * @return 日期
     */
    public static Date parseDate(String date, String form){
        SimpleDateFormat sdf = new SimpleDateFormat(form);
        Date date1 = null;
        try {
            date1 = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date1;
    }

    /**
     * Date转字符串  （根据指定的格式将Date转换成字符串）
     *
     * @param date Date类
     * @param form 格式
     * @return 日期字符串
     */
    public static String dateString(Date date, String form) {
        SimpleDateFormat sdf = new SimpleDateFormat(form);
        return sdf.format(date);
    }


    /**
     * 使用默认格式yyyy-MM-dd将Date转字符串
     *
     * @param date
     * @return
     */
    public static String dateString(Date date) {
        return dateString(date, "yyyy-MM-dd");
    }


    /**
     * 使用默认格式yyyy-MM-dd将字符串日期转Date
     * @param date
     * @return 转换后的Date日期
     * @throws ParseException
     */
    public static Date parseDate(String date) {
        Date parseDate;
        parseDate = parseDate(date, "yyyy-MM-dd");
        return parseDate;
    }

    /**
     * 根据指定的开始与结束时间获取间隔天数
     * @param from 开始时间
     * @param to 结束时间
     * @return
     */
    public static long getDays(LocalDate from, LocalDate to) {
        long days = 0;
        if (from.isBefore(to)){
            //时间段
            Duration duration = Duration.between(from, to);
            //将时间段转换成天数
            days = duration.toDays();
            //根据指定的字段获取
//            duration.get(ChronoUnit.DAYS);
        }else {
            System.out.println("开始时间必须在结束之后");
            //实际中我们一般会以异常的形式告知用户
        }
        return days;
    }


    /**
     * 获取两个指定日期的相差天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int dayReduce(Date date1, Date date2) {
        int day;
        if (date1.after(date2)) {
            day = (int) ((date1.getTime() - date2.getTime()) / (24 * 60 * 60 * 1000));
        } else {
            day = (int) ((date2.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000));
        }
        return day;
    }

    /**
     * 计算年龄
     * @param birthday 出生日期
     * @return
     */
    public static int getAge(LocalDate birthday){
        int age = 0;
        //判断出生日期在今天之前
        if (birthday.isBefore(LocalDate.now())){
            //获取出生日期到今天的间隔 以 年 月 日 为单位
            Period period = Period.between(birthday,LocalDate.now());
            //间隔的年份就是年龄
            age = period.getYears();
        }else {
            System.out.println("出生日期不允许在今天之后");
        }
        return age;
    }


    /**
     * 根据输入的日期计算年龄
     * @param date 出生日期
     * @return
     */
    public static int getAge(String date) {
        //今天
        Calendar today = Calendar.getInstance();
        //表示出生日期
        Calendar born = Calendar.getInstance();
        //设定出生日期
        born.setTime(parseDate(date));
        //当前年份减出生年份
        int age = today.getWeekYear() - born.getWeekYear();

        //如果还没过今年生日年龄减一岁    今天是2022 01 18   2000 01 15
        if (today.get(Calendar.MONTH) <= born.get(Calendar.MONTH)
                && today.get(Calendar.DAY_OF_MONTH) < born.get(Calendar.DAY_OF_MONTH)) {
            age--;
        }
        return age;
    }


    /**
     * 获取指定日期为所在周的星期几的日期
     *
     * @param date 指定日期
     * @param week 指定的周几  国内 周一 1 2 3 .... 7   国外  周日 1  周一 2 .....周六 7
     * @return
     */
    public static Date week(Date date, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        //适合国外的周
        calendar.set(Calendar.DAY_OF_WEEK, (week == 7 ? 1 : week + 1));
        //如果是国内的周   需要注意周日和国外的周日
        Date date1 = calendar.getTime();
        return date1;
    }


    /**
     * 根据传入的毫秒值返回字符串类型日期
     *
     * @param ms
     * @return yyyy-MM-dd
     */
    public static String millisecond(long ms) {
        return dateString(new Date(ms));
    }


    /**
     * 判断时间是否在指定的时间段之内
     *
     * @param date  指定时间
     * @param front 开始时间
     * @param after 结束时间
     * @return
     */
    public static boolean betweenDate(Date date, Date front, Date after) {
        return date.after(front) && date.before(after);
    }

    /**
     * 获取当前周截止时间 星期天
     *
     * @param date
     * @return
     */
    public static Date sunday(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK, 7);
        return calendar.getTime();
    }


    /**
     * 获取当前周开始时间 周一
     *
     * @param date
     * @return
     */
    public static Date monday(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK, 1);
        return calendar.getTime();
    }


    /**
     * 获取某月多少天
     *
     * @param year
     * @param month
     * @return
     * @throws ParseException
     */
    public static int monthDay(int year, int month){
        Calendar calendar = Calendar.getInstance();
        //设置当前日期为用户指定的年 月 1日
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, 1);
        //获取1号是周几  默认从周日开始1.....
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }


}
